iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 12
0

Promise 是用來處理非同步行為,最常拿來處理 AJAX 的行為,其他非同步行為也很適合。

未使用 promise 的 ajax 範例

// 使用兩個外部套件 1. jQuery 2. axios(基於 Promise 遠端請求工具) 
const url = 'https://randomuser.me/api/' // 對此網址發出請求,回傳JOSN

// 方式一
$.ajax({
    url: url,
}).done(function (res) {
    console.log(res);
});

// 方式二 (randomuser.me網站提供的方式,結果跟方式一同)
$.ajax({
   url:'https: // randomuser.me/api/'
   dataType: 'json',
   success: function (data) {
       console.log(data);
   }
});
  • ajax 除了用 done 方式抓取,也可以用 success 來抓取,也有 jQuery 抓取方式等各種方式。
    重上述範例新增 data 來抓取資料
const url = 'https://randomuser.me/api/'
let data = {};  // 建立 data 空物件
$.ajax({
    url: url,
}).done(function (res) {
    console.log(res);
    data = res.results;
});
console.log(data);  // 此時 data 出來結果是空物件
  • 輸出 data 結果出來是空物件,是因為非同步行為,console.log(data) 會比 $.ajax 先執行,等 console.log 結果出來,再來才是執行 $.ajax 結果。
  • 把 console.log(data) 放入 $.ajax 行為中 done 裡面,解決非同步行為,其他行為亦然。
$.ajax({
    url: url,
}).done(function (res) {
    // console.log(res);
    data = res.results;
    console.log(res);   // 放入 done 裡面
});

試著抓兩筆資料,一筆隨機資料,一筆特定資料(利用 randomuser.me 網站提供 seed 的方式)

$.ajax({
    url: url,
}).done(function (res) {
    const seed = res.info.seed;
    console.log(seed, res);
    $.ajax({
        url: `${ url }?seed-${ seed}`, // 利用樣板字面值,在 url 放入特定 seed
    }).done(function (res2) {
        console.log(res2);   
    });
});
  • 在 $.ajax 的 done 裡在呼叫一個 $.ajax,變成巢狀結構。
  • 如果要在抓第三次,就會在第二次 $.ajax 的 done 裡呼叫 $.ajax,一直抓下去就變成無限巢狀了。
  • 出現非同步常見問題 - 回呼地獄。

常見的非同步問題 (不限於AJAX)

  1. 回呼地獄
  2. 寫法不一致
  3. 無法同時執行(jQuery有並行寫法,但不直覺)

改用 promise 的 ajax 範例 (使用 axios 方法)

解決寫法不一致,promise 的 axios 有固定結構寫法

axios.get(url)  // 使用 get 來取得遠端資料
    .then((res) => {  // 連接都用 .then 來開始串接
        console.log(res)   
    })

解決回呼地獄,使用串接語法

axios.get(url) 
    .then((res) => { 
       console.log(1, res)  // 輸出第一次
       const seed = res.data.info.seed; // 將 seed 方法定義在 data 裡面
       return axios.get('$furl]?seed-$fseed ')  // 回傳呼叫第二次
    })
    .then((res) {
       console.log(2, res)  // 輸出第二次
    })

解決無法同時執行,使用 promise.all 陣列方式來同時多個請求。

promise.all([axios.get(url), axios.get(url)])
    .then(([res, res2])) => {
        console.log(res1, res2)
    })

上一篇
11. Event Queue
下一篇
13. Promise概念與串接
系列文
JS 作品實戰應用 - Vue 電商網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言